<template>
  <div class="app-container">
    <!-- <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <div id="pieChart" style="width: 400px; height: 300px;"></div>
    </el-form> -->

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:records:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:records:export']"
        >导出</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="info"
          plain
          icon="el-icon-data-line"
          size="mini"
          @click="handleDeptStats"
          v-hasPermi="['system:records:list']"
        >部门考勤统计</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="recordsList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="记录ID" align="center" prop="id" />
      <el-table-column label="用户姓名" align="center" prop="userName">
        <template slot-scope="scope">
          <span>{{ scope.row.userName }}</span>
        </template>
      </el-table-column>
      <el-table-column label="上班打卡时间" align="center" prop="checkInTime" width="180">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.checkInTime, '{y}-{m}-{d} {h}:{i}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="下班打卡时间" align="center" prop="checkOutTime" width="180">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.checkOutTime, '{y}-{m}-{d} {h}:{i}') }}</span>
        </template>
      </el-table-column>
      <!-- <el-table-column label="上班打卡方式" align="center" prop="checkInMethod" width="120">
        <template slot-scope="scope">
          <el-tag :type="getMethodTagType(scope.row.checkInMethod)" effect="light" size="small">
            {{ translateMethod(scope.row.checkInMethod) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="下班打卡方式" align="center" prop="checkOutMethod" width="120">
        <template slot-scope="scope">
          <el-tag :type="getMethodTagType(scope.row.checkOutMethod)" effect="light" size="small">
            {{ translateMethod(scope.row.checkOutMethod) }}
          </el-tag>
        </template>
      </el-table-column> -->
      <el-table-column label="考勤日期" align="center" prop="workDate" width="120">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.workDate, '{y}-{m}-{d}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="考勤状态" align="center" prop="status" width="100">
        <template slot-scope="scope">
          <el-tag :type="getStatusTagType(scope.row.status)" :effect="scope.row.status === 'NORMAL' ? 'dark' : 'light'" size="small">
            {{ translateStatus(scope.row.status) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="是否已提醒" align="center" prop="reminded" width="90">
        <template slot-scope="scope">
          <el-tag :type="scope.row.reminded ? 'success' : 'info'" size="small">
            {{ scope.row.reminded ? '已提醒' : '未提醒' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="备注信息" align="center" prop="notes" show-overflow-tooltip />
      <el-table-column label="记录创建时间" align="center" prop="createdTime" width="180">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.createdTime, '{y}-{m}-{d} {h}:{i}') }}</span>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 部门考勤统计对话框 -->
    <el-dialog title="部门考勤统计" :visible.sync="deptStatsVisible" width="1000px" append-to-body>
      <el-form :model="deptQueryParams" ref="deptQueryForm" size="small" :inline="true">
        <el-form-item label="部门名称" prop="deptName">
          <el-input
            v-model="deptQueryParams.deptName"
            placeholder="请输入部门名称"
            clearable
            @keyup.enter.native="handleDeptQuery"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleDeptQuery">搜索</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetDeptQuery">重置</el-button>
        </el-form-item>
      </el-form>

      <el-tabs v-model="activeTab">
        <el-tab-pane label="部门统计" name="dept">
          <div id="deptPieChart" style="width: 100%; height: 400px;"></div>
        </el-tab-pane>
        <el-tab-pane label="详细数据" name="detail">
          <el-table :data="deptStatsData" border row-key="deptId"
                    :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
            <el-table-column prop="deptName" label="部门名称" align="center" width="200">
              <template slot-scope="scope">
                <span v-if="scope.row.level > 0" v-for="space in scope.row.level"
                      :key="space" style="display: inline-block; width: 20px;"></span>
                <span v-if="scope.row.level > 0">└─ </span>
                {{ scope.row.deptName }}
              </template>
            </el-table-column>
            <el-table-column prop="normalCount" label="正常" align="center"></el-table-column>
            <el-table-column prop="lateCount" label="迟到" align="center"></el-table-column>
            <el-table-column prop="absentCount" label="缺勤" align="center"></el-table-column>
            <el-table-column prop="exceptionCount" label="异常" align="center"></el-table-column>
            <el-table-column prop="earlyLeaveCount" label="早退" align="center"></el-table-column>
            <el-table-column prop="totalAttendance" label="总人数" align="center"></el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>
  </div>
</template>

<script>
import {
  listRecords,
  delRecords,
  getTodayCheckInStats,
  getDeptAttendanceStats
} from "@/api/system/records";
import * as echarts from 'echarts';
import { debounce } from 'lodash';

export default {
  name: "Records",
  data() {
    return {
      // 打卡方式选项
      methodOptions: [
        { value: 'NORMAL', label: '标准打卡' },
        { value: 'FACE', label: '人脸识别' },
        { value: 'NFC', label: 'NFC刷卡' },
        { value: 'QR_CODE', label: '扫码打卡' },
        { value: 'LOCATION', label: '定位打卡' },
        { value: 'OTHER', label: '其他方式' }
      ],

      // 考勤状态选项
      statusOptions: [
        { value: 'NORMAL', label: '正常' },
        { value: 'LATE', label: '迟到' },
        { value: 'EARLY_LEAVE', label: '早退' },
        { value: 'ABSENT', label: '缺勤' },
        { value: 'BUSINESS_TRIP', label: '出差' },
        { value: 'LEAVE', label: '请假' },
        { value: 'OVERTIME', label: '加班' }
      ],

      loading: true,
      ids: [],
      single: true,
      multiple: true,
      showSearch: true,
      total: 0,
      recordsList: [],
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        checkInTime: null,
        checkOutTime: null,
        checkInMethod: null,
        checkOutMethod: null,
        workDate: null,
        status: null,
        reminded: null,
        notes: null,
        createdTime: null,
        updatedTime: null,
        userName: null
      },
      deptStatsVisible: false,
      activeTab: 'dept',
      deptStatsData: [],
      deptPieChart: null,
      deptQueryParams: {
        deptName: null
      },
      originalDeptStatsData: []
    };
  },
  created() {
    this.getList();
  },
  mounted() {
    this.loadTodayCheckInStats();
  },
  beforeDestroy() {
    if (this.deptPieChart) {
      window.removeEventListener('resize', this.handleDeptChartResize);
      this.deptPieChart.dispose();
    }
  },
  methods: {
    // 翻译方法
    translateMethod(method) {
      const methodMap = {
        'NORMAL': '标准打卡',
        'FACE': '人脸识别',
        'NFC': 'NFC刷卡',
        'QR_CODE': '扫码打卡',
        'LOCATION': '定位打卡',
        'OTHER': '其他方式'
      };
      return methodMap[method] || method;
    },

    translateStatus(status) {
      const statusMap = {
        'NORMAL': '正常',
        'LATE': '迟到',
        'EARLY_LEAVE': '早退',
        'ABSENT': '缺勤',
        'BUSINESS_TRIP': '出差',
        'LEAVE': '请假',
        'OVERTIME': '加班'
      };
      return statusMap[status] || status;
    },

    getMethodTagType(method) {
      const typeMap = {
        'NORMAL': 'primary',
        'FACE': 'success',
        'NFC': 'warning',
        'default': 'info'
      };
      return typeMap[method] || typeMap.default;
    },

    getStatusTagType(status) {
      const typeMap = {
        'NORMAL': 'success',
        'LATE': 'warning',
        'EARLY_LEAVE': 'warning',
        'ABSENT': 'danger',
        'default': 'info'
      };
      return typeMap[status] || typeMap.default;
    },

    // 原有方法
    getList() {
      this.loading = true;
      listRecords(this.queryParams).then(response => {
        this.recordsList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length!==1
      this.multiple = !selection.length
    },
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal.confirm('是否确认删除考勤记录编号为"' + ids + '"的数据项？').then(function() {
        return delRecords(ids);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    handleExport() {
      this.download('system/records/export', {
        ...this.queryParams
      }, `records_${new Date().getTime()}.xlsx`)
    },
    loadTodayCheckInStats() {
      getTodayCheckInStats().then(response => {
        const charData = response.data.map(item => ({
          name: this.translateStatus(item.stats),
          value: item.count,
          itemStyle: { color: this.getStatusColor(item.stats) }
        }));
        this.renderChart(charData);
      });
    },
    getStatusColor(status) {
      const colorMap = {
        'NORMAL': '#67C23A',
        'LATE': '#E6A23C',
        'ABSENT': '#F56C6C',
        'EARLY_LEAVE': '#E6A23C',
        'default': '#909399'
      };
      return colorMap[status] || colorMap.default;
    },
    renderChart(data) {
      let chart = echarts.init(document.getElementById('pieChart'));
      chart.setOption({
        title: { text: '今日员工打卡情况', left: 'center' },
        tooltip: { trigger: 'item' },
        legend: { orient: 'vertical', left: 'left' },
        series: [{ type: 'pie', radius: '50%', data }]
      });
    },
    handleDeptStats() {
      this.deptStatsVisible = true;
      this.resetDeptQuery();
    },
    getDeptAttendanceStats() {
      getDeptAttendanceStats(this.deptQueryParams.deptName).then(response => {
        const data = response.data;
        const deptTree = this.buildDeptTree(data);
        this.deptStatsData = deptTree;
        this.originalDeptStatsData = [...deptTree];
        this.$nextTick(() => {
          this.renderDeptPieChart();
        });
      });
    },
    buildDeptTree(data) {
      const tree = [];
      const map = {};

      data.forEach(item => {
        map[item.deptId] = {
          ...item,
          children: [],
          level: 0
        };
      });

      data.forEach(item => {
        const node = map[item.deptId];
        if (item.parentId === 0 || !map[item.parentId]) {
          tree.push(node);
        } else {
          const parent = map[item.parentId];
          node.level = parent.level + 1;
          parent.children.push(node);
        }
      });

      this.calculateTreeStats(tree);
      return tree;
    },
    calculateTreeStats(nodes) {
      nodes.forEach(node => {
        if (node.children && node.children.length > 0) {
          this.calculateTreeStats(node.children);
          node.normalCount = node.children.reduce((sum, child) => sum + (child.normalCount || 0), 0);
          node.lateCount = node.children.reduce((sum, child) => sum + (child.lateCount || 0), 0);
          node.absentCount = node.children.reduce((sum, child) => sum + (child.absentCount || 0), 0);
          node.exceptionCount = node.children.reduce((sum, child) => sum + (child.exceptionCount || 0), 0);
          node.earlyLeaveCount = node.children.reduce((sum, child) => sum + (child.earlyLeaveCount || 0), 0);
          node.totalAttendance = node.children.reduce((sum, child) => sum + (child.totalAttendance || 0), 0);
        }
      });
    },
    handleDeptQuery() {
      this.getDeptAttendanceStats();
    },
    resetDeptQuery() {
      this.deptQueryParams.deptName = null;
      this.getDeptAttendanceStats();
    },
    renderDeptPieChart() {
      if (!this.deptStatsData || this.deptStatsData.length === 0) {
        if (this.deptPieChart) {
          this.deptPieChart.dispose();
          const emptyOption = {
            title: {
              text: '没有找到匹配的部门数据',
              left: 'center',
              top: 'center',
              textStyle: {
                color: '#999',
                fontSize: 16,
                fontWeight: 'normal'
              }
            }
          };
          this.deptPieChart.setOption(emptyOption, true);
        }
        return;
      }

      if (this.deptPieChart) {
        this.deptPieChart.dispose();
      }

      this.deptPieChart = echarts.init(document.getElementById('deptPieChart'));

      const seriesData = [
        { name: '正常', value: this.sumByKey('normalCount') },
        { name: '迟到', value: this.sumByKey('lateCount') },
        { name: '缺勤', value: this.sumByKey('absentCount') },
        { name: '异常', value: this.sumByKey('exceptionCount') },
        { name: '早退', value: this.sumByKey('earlyLeaveCount') }
      ].filter(item => item.value > 0);

      const total = seriesData.reduce((sum, item) => sum + item.value, 0);

      const colorPalette = [
        '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#409EFF'
      ];

      const option = {
        backgroundColor: '#fff',
        title: {
          text: this.deptQueryParams.deptName
                ? `部门考勤统计 - ${this.deptQueryParams.deptName}`
                : '部门考勤统计概览',
          left: 'center',
          top: 20,
          textStyle: {
            color: '#333',
            fontSize: 16,
            fontWeight: 'bold'
          },
          subtext: total ? `总计: ${total}人次` : '',
          subtextStyle: {
            color: '#666',
            fontSize: 12
          }
        },
        tooltip: {
          trigger: 'item',
          formatter: params => {
            const percent = total ? (params.value / total * 100).toFixed(2) : 0;
            return `${params.name}<br/>数量: ${params.value}<br/>占比: ${percent}%<br/>`;
          },
          backgroundColor: 'rgba(50,50,50,0.7)',
          borderColor: '#333',
          textStyle: {
            color: '#fff'
          }
        },
        legend: {
          type: 'scroll',
          orient: 'vertical',
          right: 10,
          top: 'center',
          data: seriesData.map(item => item.name),
          textStyle: {
            color: '#666'
          }
        },
        series: [{
          name: '考勤状态',
          type: 'pie',
          radius: ['40%', '70%'],
          center: ['40%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 6,
            borderColor: '#fff',
            borderWidth: 2,
            color: params => colorPalette[params.dataIndex % colorPalette.length]
          },
          label: {
            show: true,
            formatter: params => {
              const percent = total ? (params.value / total * 100).toFixed(1) : 0;
              return `${params.name}\n${percent}%`;
            },
            color: '#333',
            fontSize: 12,
            lineHeight: 16
          },
          emphasis: {
            label: {
              show: true,
              fontSize: '14',
              fontWeight: 'bold'
            },
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          },
          labelLine: {
            show: true,
            length: 10,
            length2: 10
          },
          data: seriesData,
          animationType: 'scale',
          animationEasing: 'elasticOut',
          animationDelay: idx => idx * 100
        }]
      };

      this.deptPieChart.setOption(option, true);

      const handleResize = debounce(() => {
        this.deptPieChart && this.deptPieChart.resize();
      }, 300);
      window.addEventListener('resize', handleResize);

      this.$once('hook:beforeDestroy', () => {
        window.removeEventListener('resize', handleResize);
      });
    },
    sumByKey(key) {
      return this.deptStatsData.reduce((sum, item) => sum + (item[key] || 0), 0);
    },
    handleDeptChartResize: debounce(function() {
      if (this.deptPieChart) {
        this.deptPieChart.resize();
      }
    }, 300)
  }
};
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.el-table {
  margin-top: 20px;
}

#pieChart, #deptPieChart {
  margin: 0 auto;
}

/* 标签样式优化 */
.el-tag {
  margin: 2px;
  font-size: 12px;
  min-width: 60px;
  text-align: center;
  padding: 0 6px;
  height: 24px;
  line-height: 22px;
}

.el-tag--success {
  background-color: #f0f9eb;
  border-color: #e1f3d8;
  color: #67c23a;
}

.el-tag--warning {
  background-color: #fdf6ec;
  border-color: #faecd8;
  color: #e6a23c;
}

.el-tag--danger {
  background-color: #fef0f0;
  border-color: #fde2e2;
  color: #f56c6c;
}

.el-tag--info {
  background-color: #f4f4f5;
  border-color: #e9e9eb;
  color: #909399;
}

.el-tag--primary {
  background-color: #ecf5ff;
  border-color: #d9ecff;
  color: #409eff;
}
</style>
